package CapaPersistencia;


import CapaLogica.GestionResort;
import CapaDatos.Restaurante;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;


/**
 * Clase de persistencia de implementacion DAO con tecnologia
 * XML para el dominio de Cliente
 *
 */
public class DAORestauranteXML implements IDAORestaurante {

    /** variable que contiene la raiz del documento Xml*/

    private Element root;
    /** variable que contiene la localizacion del archivo xml*/

    private String fileLocation = "C:/ArchivosXml/Restaurantes.xml";
    /**
     * constructor por defecto que inicia los valores para trabajar con el documento
     * xml
     */
    public DAORestauranteXML() {
        try {
            SAXBuilder builder = new SAXBuilder(false);
            Document doc = null;
            doc = builder.build(fileLocation);
            root = doc.getRootElement();
        } catch (JDOMException ex) {
            System.out.println("No se pudo iniciar la operacion por: " + ex.getMessage());
        } catch (IOException ex) {
            System.out.println("No se pudo iniciar la operacion por: " + ex.getMessage());
        }
    }

    /**
     * firma para pasar un objeto de dominio cliente a un elemento entendible
     * por la libreria jdom para dar soporte al trabajo con xml
     * @param restaurante objeto cliente a traducir
     * @return objeto tipo element para el xml
     */
    private Element RestaurantetoXmlElement(Restaurante restaurante) {

        Element reservaTrans = new Element("restaurante");
        Element ID = new Element("ID");
        ID.setText(restaurante.getID());
        Element ubicacion = new Element("ubicacion");
        ubicacion.setText(restaurante.getUbicacion());
        Element capComensales = new Element("capComensales");
        capComensales.setText(String.valueOf(restaurante.getCapComensales()));
        Element comidas = new Element("comidas");
        comidas.setText(restaurante.getComidas());


        reservaTrans.addContent(ID);
        reservaTrans.addContent(ubicacion);
        reservaTrans.addContent(capComensales);
        reservaTrans.addContent(comidas);

        return reservaTrans;
    }

    /**
     * firma para pasar de on objeto de tipo elemento a un objeto de dominio
     * para dar soporte a la aplicacion
     * @param element elemento a traducir
     * @return objeto de dominio cliente
     */
    private Restaurante restauranteToObject(Element element) throws ParseException {
        Restaurante restaurante = new Restaurante();

        restaurante.setID(element.getChildText("ID"));
        restaurante.setUbicacion(element.getChildText("ubicacion"));
        String capComensales = element.getChildText("capComensales");
        restaurante.setCapComensales(Integer.parseInt(capComensales));
        restaurante.setComidas((element.getChildText("comidas")));


        return restaurante;
    }

    /**
     * Operacion para guardar en el documento Xml los cambios efectuados
     * @return true si se cumplio la operacion con exito, false en caso contrario
     */
    private boolean updateDocument() {
        try {
            XMLOutputter out = new XMLOutputter();
            FileOutputStream file = new FileOutputStream(fileLocation);
            out.output(root, file);
            file.flush();
            file.close();
            return true;
        } catch (Exception e) {
            System.out.println("error: " + e.getMessage());
            return false;
        }
    }

    /**
     * Operacion que busca un elemento que cumpla con una condicion en el id del xml
     * @param raiz la raiz del documento xml
     * @param dato el dato a comparar para la busqueda del elemento. Debe ser el identificador
     * @return retorna el elemento si existe con la condicion, en caso contrario retorna null
     */
    public static Element buscar(List raiz, String dato) {
        Iterator i = raiz.iterator();
        while (i.hasNext()) {
            Element e = (Element) i.next();
            if (dato.equals(e.getChild("ID").getText())) {
                return e;
            }
        }
        return null;
    }

    /**
     * firma para agregar un nuevo cliente
     * @param restaurante objeto cliente a agregar
     * @return valor boleano con la condicion de exito
     */
    public boolean agregarRestaurante(Restaurante restaurante) {
        boolean resultado = false;
        root.addContent(RestaurantetoXmlElement(restaurante));
        GestionResort.getLosRestaurantes().agregarElemento(restaurante);
        resultado = updateDocument();
        return resultado;
    }

    /**
     * firma para buscar un cliente
     * @param ID ID del restaurante a buscar
     * @return objeto restaurante con sus datos segun busqueda
     */
    public Restaurante buscarRestaurante(String ID) {
        Element aux = new Element("restaurante");
        List salones = this.root.getChildren("restaurante");
        while (aux != null) {
            aux = DAORestauranteXML.buscar(salones, ID);
            if (aux != null) {
                try {
                    return restauranteToObject(aux);
                } catch (ParseException ex) {
                    System.out.println(ex.getMessage());
                }
            }
        }
        return null;
    }

    /**
     * firma para actualizar un restaurante
     * @param restaurante objeto restaurante a actualizar
     * @return valor boleano con la condicion de exito
     */
    public boolean actualizarRestaurante(Restaurante restaurante) {
        boolean resultado = false;
        Element aux = new Element("restaurante");
        List salones = this.root.getChildren("restaurante");
        while (aux != null) {
            aux = DAORestauranteXML.buscar(salones, restaurante.getID());
            if (aux != null) {
                salones.remove(aux);
                resultado = updateDocument();
            }
        }
        GestionResort.getLosRestaurantes().agregarElemento(restaurante);
        agregarRestaurante(restaurante);
        return resultado;
    }

    /**
     * firma para borrar un restaurante
     * @param ID ID del restaurante a borrar
     * @return valor boleano con la condicion de exito
     */
    public boolean borrarRestaurante(String ID) {
        boolean resultado = false;
        Element aux = new Element("restaurante");
        List salones = this.root.getChildren("restaurante");
        while (aux != null) {
            aux = DAORestauranteXML.buscar(salones, ID);
            if (aux != null) {
                salones.remove(aux);
              GestionResort.getLosRestaurantes().eliminarRestaurantePorId(ID);
                resultado = updateDocument();
            }
        }
        return resultado;
    }

    /**
     * firma para obtener todas las reservas
     * @return ArrayList con todos los objetos reserva
     */
    public ArrayList<Restaurante> todosLosRestaurantes() {
        ArrayList<Restaurante> resultado = new ArrayList<Restaurante>();
        for (Object it : root.getChildren()) {
            Element xmlElem = (Element) it;
            try {
                resultado.add(restauranteToObject(xmlElem));
            } catch (ParseException ex) {
                System.out.println(ex.getMessage());
            }
        }
        return resultado;
    }
}
